/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */


var EXPORTED_SYMBOLS =
[
    "FolderEntry",
    "recentEntry",
    "separatorEntry"
];

const Cc = Components.classes;
const Ci = Components.interfaces;
const Cu = Components.utils;

Cu.import("resource://savefileto/common.jsm");


const recentEntry = {type: "recent"};
const separatorEntry = {type: "separator"};


function FolderEntry(entry, compare, filter)
{
    this.type = (entry.menu ? "menu" : "item");
    this.label = entry.label;
    this.labelLower = entry.label.toLowerCase();
    this.path = entry.path;
    this.pathLabel = (entry.pathLabel ? entry.pathLabel : entry.label);
    this._file = entry.file;
    
    this.compare = compare;
    this.filter = filter;
}

FolderEntry.prototype =
{
    get file()
    {
        if (! this._file)
            this._file = getFile(this.path);
        
        return this._file;
    },
    
    get hidden()
    {
        var file = this.file;
        return (! (file && file.exists() && file.isDirectory()));
    },
    
    get hasChildren()
    {
        return ((this.type == "menu") && this._getChildren(true));
    },
    
    get children()
    {
        return ((this.type == "menu") ? this._getChildren(false) : []);
    },
    
    _getChildren: function FE__getChildren(searchOnly)
    {
        var children = [];
        
        var pathLabel = this.pathLabel;
        var compare = this.compare;
        var filter = this.filter;
        
        // try is required for ff+windows bugs #5 and #12
        var fileEnumerator = this.file.directoryEntries;
        while (fileEnumerator.hasMoreElements())
        try
        {
            var file = fileEnumerator.getNext().QueryInterface(Ci.nsIFile);
            
            if ((! file.isDirectory()) || file.isHidden())
                continue;
            if (filter && filter(file))
                continue;
            if (searchOnly)
                return true;
            
            var entry =
            {
                menu: true,
                label: file.leafName,
                path: file.path,
                pathLabel: pathLabel + PATH_DELIM + file.leafName,
                file: file
            };
            
            entry = new FolderEntry(entry, compare, filter);
            children.push(entry);
        }
        catch (e)
        {
            Cu.reportError(e);
        }
        
        if (searchOnly)
            return false;
        
        if (compare)
            children.sort(compare);
        
        return children;
    },
    
    compareTo: function FE_compareTo(entry)
    {
        var a = this.labelLower;
        var b = entry.labelLower;
        
        return ((a < b) ? -1 : ((a == b) ? 0 : 1));
    },
    
    toString: function FE_toString()
    {
        return "{type: '" + this.type + "', label: '" + this.label + "', path: '" + this.path + "'}";
    }
}
